/*!
 * @file /app/mvp_hardware.h
 * @date 2021-06-11
 * 
 * Last Edit: 2021-12-07
 * 
 * @author Ma Chao
 * Contact: machao@macro-video.com
 * Copyright (C) 2021 M@cro-video Technologies Co. All rights reserved
 * 
 * @brief 宏视平台硬件资源使用需适配接口
 * 
 * @note 
 **/

#ifndef __MVP_HARDWARE_H__
#define __MVP_HARDWARE_H__

#include "mvvcd.h"

#if __cplusplus
extern "C" {
#endif

#pragma region sdcard
//=============================== [sdcard] ==============================//
typedef enum sdcard_type
{
  SDCARD_FAT32_FORMAT      =  1, ///< fat32
  SDCARD_EXFAT_FORMAT,          ///< exfat
}MVP_SDCARD_TYPE_E;

/**
 * @brief  SD卡挂载
 * @return 
 * - success : MVVCD_EC_SUCCESS
 */
mv_s32_t mvp_sdcard_mount();

/**
 * @brief  SD卡重新挂载
 * @return 
 * - success : MVVCD_EC_SUCCESS
 */
mv_s32_t mvp_sdcard_remount();

/**
 * @brief  SD卡卸载
 * @return 
 * - success : MVVCD_EC_SUCCESS
 */
mv_s32_t mvp_sdcard_umount();

/**
 * @brief  SD卡格式化
 * @return 
 * - success : MVVCD_EC_SUCCESS
 */
mv_s32_t mvp_sdcard_format();

/**
 * @brief  SD卡插拔状态获取
 * @return 
 * - success : [0/1]
 * -  failed : -1
 */
mv_s32_t mvp_sdcard_insert_status_check();

/**
 * @brief  SD卡是否需要格式化检测(用于检查卡的格式是否符合我们的要求，不符合就需要格式化成我们想要的)
 * @param  format [in] 卡的格式
 * @param  cluster_size [in] 簇大小
 * @return 
 * - true : 1
 * - false : 0
 */
mv_bool_t mvp_sdcard_format_check(mv_s32_t format, mv_s32_t cluster_size);

/**
 * @brief  SD卡读写状态检查
 * @return 
 * - success : MVVCD_EC_SUCCESS
 * - failed ： errno
 * @attention xm方案经常出现access判断TF卡挂载目录是有读写权限的，
 *            但是实际上读写权限已经异常，因此搞一个函数详细判断下读写权限
 */
mv_s32_t mvp_sdcard_rwpermission_check();

mv_cv8ptr_t mvp_sdcard_mmcblk_check(mv_u8_t u8_dchn);

/**
 * @brief 返回当前存在的有效设备节点路径
 * @return
 * - success : MV_TRUE/MV_FALSE
 * - failed  : NULL
*/
mv_bool_t mvp_sdcard_device_exist(mv_void_t);


#pragma endregion sdcard

#pragma region gpio
//=============================== [GPIO] ==============================//
typedef enum gpio_val
{
  GPIO_INVALID_VAL  = -1,
  GPIO_LOW_VAL      =  0, ///< 低电平
  GPIO_HIGH_VAL,          ///< 高电平
  GPIO_PUPD_DISABLE,      ///< 复用value入参，init可以精准判断是否需要disable
}MVP_GPIO_VAL_E;

typedef enum gpio_dir
{
  GPIO_INVALID_DIR = -1,
  GPIO_DIR_INPUT   =  0, ///< 输入
  GPIO_DIR_OUTPUT        ///< 输出
}MVP_GPIO_DIR_E;

typedef enum gpio_cfg
{
  GPIO_CFG_PU   =  0, ///< 上拉
  GPIO_CFG_PD         ///< 下拉
}MVP_GPIO_CFG_E;

/**
 * @brief GPIO设备open
 * @return 
 * - success : MVVCD_EC_SUCCESS
 * -  failed : < 0
 */
mv_s32_t mvp_gpio_dev_open();

/**
 * @brief GPIO设备close
 */
mv_void_t mvp_gpio_dev_close();

/**
 * @brief GPIO资源初始化
 * @param s32_pin [in] 引脚号
 * @return 
 * - success : MVVCD_EC_SUCCESS
 * -  failed : < 0
 */
mv_s32_t mvp_gpio_init(mv_s32_t s32_pin);

/**
 * @brief GPIO资源反初始化
 * @param s32_pin [in] gpio引脚号
 */
mv_void_t mvp_gpio_uninit(mv_s32_t s32_pin);

/**
 * @brief GPIO设置输出电平
 * @param s32_pin [in] 引脚号
 * @param val     [in] 电平值[GPIO_LOW_VAL/GPIO_LOW_HIGH]
 * @return
 * - success : MVVCD_EC_SUCCESS
 *  - failed : < 0
 */
mv_s32_t mvp_gpio_set_out_val(mv_s32_t s32_pin, MVP_GPIO_VAL_E val);

/**
 * @brief GPIO读取电平
 * @param s32_pin [in] 引脚
 * @return
 * - success : 电平值[0/1]
 * -  failed : < 0
 */
mv_s32_t mvp_gpio_get_input_val(mv_s32_t s32_pin);

/**
 * @brief pin设置为gpio模式
 * @param s32_pin [in] 引脚号
 * @return
 * - success : MVVCD_EC_SUCCESS
 * -  failed : < 0
 */
mv_s32_t mvp_pin_set_as_gpio(mv_s32_t s32_pin);

/**
 * @brief GPIO设置输入、输出模式
 * @param s32_pin  [in] 引脚号 
 * @param s32_mode [in] [GPIO_DIR_INPUT/GPIO_DIR_OUTPUT]
 * @return
 * - success : MVVCD_EC_SUCCESS
 * - failed  : < 0
 */
mv_s32_t mvp_gpio_set_dir_mode(mv_s32_t s32_pin, mv_s32_t s32_mode, mv_s32_t s32_def_val);

/**
 * @brief GPIO设置上拉、下拉配置
 * @param s32_pin  [in] 引脚号 
 * @param s32_pupd_config [in] [GPIO_CFG_PU/GPIO_CFG_PD]
 * @return
 * - success : MVVCD_EC_SUCCESS
 * - failed  : < 0
 */
mv_s32_t mvp_gpio_set_pupd_config(mv_s32_t s32_pin, mv_s32_t s32_pupd_config);

/**
 * @brief 获取GPIO上拉、下拉配置
 * @param s32_pin  [in] 引脚号 
 * @return
 * - success : MVP_GPIO_CFG_E
 * - failed  : < 0
 */
mv_s32_t mvp_gpio_get_pupd_config(mv_s32_t s32_pin);
#pragma endregion gpio

#pragma region adc
//=============================== [adc] ==============================//
typedef enum _adc_chn
{
	ADC_CHN_IRFEED    =  0, ///< 光敏adc值读取通道
	ADC_CHN_BATTERY       , ///< 电池电量读取adc通道
	ADC_CHN_SMOKE_DET     , ///< 烟雾检测读取adc通道
  ADC_CHN_BTHON         ,
}MVP_ADC_CHN_E;

/**
 * @brief  打开adc设备
 * @param  pv8_dev [in] 设备节点路径
 * @return  
 * - success : MVVCD_EC_SUCCESS
 * -  failed : < 0
 */
mv_s32_t mvp_saradc_dev_open(MVP_ADC_CHN_E adc_chn);

/**
 * @brief  adc读取数值
 * @param  s32_adc_fd [in] 文件描述符
 * @return
 * - success : adc 数值
 * -  failed : < 0
 */
mv_s32_t mvp_saradc_read(MVP_ADC_CHN_E adc_chn);

/**
 * @brief  关闭adc设备 
 * @param  s32_adc_fd [in] 文件描述符
 */
mv_void_t mvp_saradc_dev_close(MVP_ADC_CHN_E adc_chn);
#pragma endregion adc

#pragma region i2c
//=============================== [i2c] ==============================//
#ifndef MVP_I2C_DEV
#if defined(DG_PC)
#define MVP_I2C_DEV    NULL
#else
#define MVP_I2C_DEV    "/dev/i2c-0"
#endif
#endif

#ifndef MVP_I2C_NUM
#define MVP_I2C_NUM   2
#endif
typedef enum _i2c_dev_type_e
{
    MVP_I2C_DEV_TYPE_AT24C02 = 0,
    MVP_I2C_DEV_TYPE_MAX,
}mvp_i2c_dev_type_e;
/**
 * @brief  打开i2c设备
 * @param  e_i2c_dev  [in] 需要初始化的I2C设备,优先匹配设备类型
 * @param  u8_channel [in] 对应I2C序号（默认0）
 * @return
 * - success : p_handle 设备的操作句柄
 *   -failed : NULL
 */
mv_vptr_t mvp_i2c_dev_open(mvp_i2c_dev_type_e e_i2c_dev, mv_u8_t u8_channel);

/**
 * @brief  i2c读取数据
 * @param  p_handle     [in] open的设备操作句柄
 * @param  pu8_sub_addr [in]  i2c读取副地址
 * @param  u8_addr_len  [in]  i2c读取--副地址长度(用于地址长度转换)
 * @param  pu8_buf      [out] i2c读取数据buffer
 * @param  s32_read_len [in] i2c读取数据长度
 * @return
 * - success : 读取字节数量
 * -  failed : < 0
 */
mv_s32_t mvp_i2c_read(mv_vptr_t p_handle, mv_u8ptr_t pu8_sub_addr, mv_u8_t u8_addr_len, mv_u8ptr_t pu8_buf, mv_s32_t s32_read_len);

/**
 * @brief  i2c写入数据
 * @param  p_handle      [in] open的设备操作句柄
 * @param  pu8_sub_addr  [in] i2c写入副地址
 * @param  u8_addr_len   [in] i2c读取--副地址长度(用于地址长度转换)
 * @param  pu8_buf       [in] i2c写入数据buffer
 * @param  s32_write_len [in] i2c写入数据长度
 * @return
 * - success : 写入字节数量
 * -  failed : < 0
 */
mv_s32_t mvp_i2c_write(mv_vptr_t p_i2c_handle, mv_u8ptr_t pu8_sub_addr, mv_u8_t u8_addr_len, mv_u8ptr_t pu8_buf, mv_s32_t s32_write_len);

/**
 * @brief  关闭i2c设备
 * @param  p_handle      [in] open的设备操作句柄
 */
mv_s32_t mvp_i2c_dev_close(mv_vptr_t p_handle);
#pragma endregion i2c

#pragma region mtd
typedef enum mtd_rw_type
{
  MTD_W_COMPLETE,
  MTD_W_SHARD,
  MTD_R_COMPLETE,
  MTD_R_SHARD,
}MVP_MTD_RW_TYPE_E;

/**
 * @brief  打开mtd块设备
 * @param  pv8_dev [in] mtd 节点路径
 * @return 
 * - success : > 0 [mtd fd]
 * -  failed : < 0
 */
mv_s32_t mvp_mtd_dev_open(mv_v8ptr_t pv8_dev);

/**
 * @brief mtd块设备数据擦除
 * @param s32_mtd_fd    [in] 文件描述符
 * @param s32_erase_len [in] 擦除长度
 * @param s32_offset    [in] 起始位置偏移量
 * @return  
 * - success : MVVCD_EC_SUCCESS
 * - failed  : < 0
 */
mv_s32_t mvp_mtd_erase(mv_s32_t s32_mtd_fd, mv_s32_t s32_erase_len, mv_s32_t s32_offset);

/**
 * @brief mtd块设备数据写入
 * @param s32_mtd_fd   [in] 文件描述符
 * @param pu8_data     [in] 写入数据buffer
 * @param s32_data_len [in] 写入数据长度
 * @param s32_offset   [in] 起始位置偏移量
 * @return 
 * - success : MVVCD_EC_SUCCESS
 * - failed  : < 0
 */
mv_s32_t mvp_mtd_write(mv_s32_t s32_mtd_fd, mv_u8_t u8_w_mode, mv_u8ptr_t pu8_data, mv_s32_t s32_data_len, mv_s32_t s32_offset,
    mv_s32_t(*data_in)(mv_u8ptr_t pu8_data, mv_s32_t s32_get_data_len));

/**
 * @brief mtd块设备数据读取
 * @param s32_mtd_fd   [in]  文件描述符
 * @param pu8_data     [out] 读取数据buffer
 * @param s32_data_len [in]  读取数据长度
 * @param s32_offset   [in]  起始位置偏移量
 * @return  
 * - success : 读取字节数目
 * - failed  : < 0
 */
mv_s32_t mvp_mtd_read(mv_s32_t s32_mtd_fd, mv_u8_t u8_r_mode, mv_u8ptr_t pu8_data, mv_s32_t s32_data_len, mv_s32_t s32_offset,
    mv_s32_t(*data_out)(mv_u8ptr_t pu8_data, mv_s32_t s32_data_len));

/**
 * @brief  关闭mtd块设备
 * @param  s32_mtd_fd [in] 文件描述符
 */
mv_void_t mvp_mtd_dev_close(mv_s32_t s32_mtd_fd);
#pragma endregion mtd

#pragma region watchdog
//=============================== [watch dog] ==============================//
typedef enum _mvp_watchdog_cliid {
	MVP_WDG_MAIN_STREAM_CLI_ID,
	MVP_WDG_SUB_STREAM_CLI_ID,
	MVP_WDG_OTA_DOWNLOAD_CLI_ID,
	MVP_WDG_UPGRADE_CLI_ID,
}MVP_WATCHDOG_CLI_ID_E;
/**
 * @brief  初始化看门狗
 * @param  wdg_timeout_s　　[in]　看门狗超时时间; 0默认30s
 * @return 
 * -success : wdg_id
 *  -failed : < 0
 */
mv_s32_t mvp_watchdog_init(MVP_WATCHDOG_CLI_ID_E wdg_id, mv_s32_t wdg_timeout_s);

/**
 * @brief 喂看门狗
 */
mv_s32_t mvp_watchdog_feed(MVP_WATCHDOG_CLI_ID_E wdg_id);

/**
 * @brief 关闭看门狗
 */
mv_void_t mvp_watchdog_uninit(MVP_WATCHDOG_CLI_ID_E wdg_id);

/**
 * @brief  设置看门狗超时时间
 * @param  sec [in] 看门狗超时时间
 * @return
 * -success : MVVCD_EC_SUCCESS
 *  -failed : < 0
 */
mv_s32_t mvp_watchdog_timeout_set(MVP_WATCHDOG_CLI_ID_E wdg_id, mv_s32_t sec);

#pragma endregion watchdog

//=============================== [ptz] ==============================//

typedef enum _ptz_type
{
  PTZ_NOT_SUPPORT  = 0x0,   ///< 不支持云台
  PTZ_ONLY_HORIZON = 0x1,   ///< 支持水平方向云台
  PTZ_ONLY_VERTICAL= 0x2,   ///< 支持垂直方向云台
  PTZ_HORIZON_VERTICAL = (PTZ_ONLY_HORIZON|PTZ_ONLY_VERTICAL), ///< 支持双方向云台
}MVP_PTZ_TYPE_E;


typedef enum _ptz_dir_flip
{
  PTZ_OPPOSITE_RUN_N = 0, ///< 不翻转
  PTZ_OPPOSITE_RUN_R = 1, ///< 翻转
  PTZ_OPPOSITE_RUN_B = 1, ///< 双方向翻转
  PTZ_OPPOSITE_RUN_H,     ///< 水平方向翻转
  PTZ_OPPOSITE_RUN_V,     ///< 垂直方向翻转
}MVP_PTZ_FLIP_E;

typedef enum _ptz_speed_level
{
  PTZ_SPEED_LEVEL_MIN = 1,
  PTZ_SPEED_LEVEL_1   = PTZ_SPEED_LEVEL_MIN,
  PTZ_SPEED_LEVEL_2,
  PTZ_SPEED_LEVEL_3,
  PTZ_SPEED_LEVEL_4,
  PTZ_SPEED_LEVEL_5,
  PTZ_SPEED_LEVEL_6,
  PTZ_SPEED_LEVEL_7,
  PTZ_SPEED_LEVEL_8,
  PTZ_SPEED_LEVEL_9,
  PTZ_SPEED_LEVEL_10,
  PTZ_SPEED_LEVEL_MAX = PTZ_SPEED_LEVEL_10,
}MVP_PTZ_SPEED_LEVEL_E;

typedef enum _ptz_turn_type
{
  PTZ_TURN_BY_CTRL = 1, ///< 手动控制旋转
  PTZ_TURN_BY_MT,       ///< 移动追踪旋转
}MVP_PTZ_TURN_TYPE_E;

typedef struct _mvp_ptz_param
{
  MVP_PTZ_TYPE_E ptz_type;    ///< 电机类型
  mv_s32_t init_angle_h;      ///< 水平初始化位置
  mv_s32_t init_angle_v;      ///< 垂直初始化位置
  mv_s32_t init_speed_level;  ///< 自检速度
  mv_s32_t vague_full_ag_H;   ///< 水平方向一周期值
  mv_s32_t vague_full_ag_V;   ///< 垂直方向一周期值
  mv_s32_t step_unit_h;       ///< 水平步长单位
  mv_s32_t step_unit_v;       ///< 垂直步长单位
  mv_s32_t s32_ptz_speed_max_limit_h; ///< 云台水平速度最大值限制
  mv_s32_t s32_ptz_speed_max_limit_v; ///< 云台垂直速度最大值限制
}MVP_PTZ_PARAM_T;

/**
 * @brief  隐私模式回调指针
 */
typedef mv_void_t (*MVP_PTZ_PRIVACY_CB)(mv_s32_t s32_py);

/**
 * @brief  云台控制初始化
 * @param  pstru_ptz_param [in] 云台相关参数
 * @return
 * - success : MVVCD_EC_SUCCESS
 * - failed  : < 0
 * @note 
 */
mv_s32_t mvp_ptz_init(MVP_PTZ_PARAM_T *param);

/**
 * @brief 云台控制初反始化
 * @return
 * - success : MVVCD_EC_SUCCESS
 * - failed  : < 0
 * @note 
 */
mv_s32_t mvp_ptz_uninit();

/**
 * @brief  云台自检
 * @param  s32_block [in] 是否阻塞等待自检完毕， 0不等待， 1等待
 * @return
 * - success : MVVCD_EC_SUCCESS
 * - failed  : < 0
 * @note 
 */
mv_s32_t mvp_ptz_self_check(mv_s32_t s32_block);

/**
 * @brief  云台方向控制
 * @param  s32_step_cnt      [in] 云台转动步数
 * @param  s32_step_distance [in] 云台转动单步步长
 * @param  speed             [in] 云台转动速度
 * @param  turn_type         [in] 旋转类型，1代表手动云台转动， 2代表移动追踪云台转动
 * @return
 * - success : MVVCD_EC_SUCCESS
 * - failed  : < 0
 * @note 
 */
mv_s32_t mvp_ptz_turn_to_left( mv_s32_t s32_step_cnt, mv_s32_t s32_step_distance, mv_s32_t speed, MVP_PTZ_TURN_TYPE_E turn_type);
mv_s32_t mvp_ptz_turn_to_right(mv_s32_t s32_step_cnt, mv_s32_t s32_step_distance, mv_s32_t speed, MVP_PTZ_TURN_TYPE_E turn_type);
mv_s32_t mvp_ptz_turn_to_up(   mv_s32_t s32_step_cnt, mv_s32_t s32_step_distance, mv_s32_t speed, MVP_PTZ_TURN_TYPE_E turn_type);
mv_s32_t mvp_ptz_turn_to_down( mv_s32_t s32_step_cnt, mv_s32_t s32_step_distance, mv_s32_t speed, MVP_PTZ_TURN_TYPE_E turn_type);

/**
 * @brief  云台当前坐标获取
 * @param  ps32_horizon  [out] 水平坐标
 * @param  ps32_vertical [out] 垂直坐标
 * @return
 * - success : MVVCD_EC_SUCCESS
 * - failed  : < 0
 * @note 
 */
mv_s32_t mvp_ptz_position_get(mv_s32ptr_t ps32_horizon, mv_s32ptr_t ps32_vertical);

/**
 * @brief 云台垂直转动至指定坐标
 * @param horizon  [in] 垂直坐标 
 * @param vertical [in] 水平坐标
 * @return
 * - success : MVVCD_EC_SUCCESS
 * - failed  : < 0
 * @note 
 */
mv_s32_t mvp_ptz_position_set(mv_s32_t s32_horizon, mv_s32_t s32_vertical, mv_s32_t speed_h, mv_s32_t speed_v);

/**
 * @brief 云台当前运动状态获取
 * @return 
 *  MV_TRUE  : 运动状态 
 *  MV_FALSE : 非运动状态
 * @note 
 */
mv_bool_t mvp_ptz_running_check();

/**
 * @brief 云台速度设置
 * @param speed_level_h [in] < MVP_PTZ_SPEED_LEVEL_E * >
 * @param speed_level_v [in] < MVP_PTZ_SPEED_LEVEL_E * >
 * @return mv_s32_t 
 * - success : MVVCD_EC_SUCCESS
 * - failed  : < 0
 */
mv_s32_t mvp_ptz_update_speed(mv_s32_t speed_level_h, mv_s32_t speed_level_v);

/**
 * @brief 更新云台位置信息到驱动(低功耗项目同步断电记忆到驱动使用)
 * @param s32_horizon [in] 水平位置
 * @param s32_vertical [in] 垂直位置
 * @return mv_s32_t 
 * - success : MVVCD_EC_SUCCESS
 * - failed  : < 0
 */
mv_s32_t mvp_ptz_position_update(mv_s32_t s32_horizon, mv_s32_t s32_vertical);

/**
 * @brief 设置隐私模式检查回调
 * @param MVP_PTZ_PRIVACY_CB [in] 隐私模式检查回调
 * @return mv_s32_t 
 * - success : MVVCD_EC_SUCCESS
 * - failed  : < 0
 */
mv_s32_t mvp_ptz_privacy_cb_set(MVP_PTZ_PRIVACY_CB privacy_check_cb);
//=============================== [uart] ==============================//
/**
 * @brief 串口设备初始化,默认8N1
 * @param p32_serial_fd   [in] 保存串口设备的fd
 * @param cv8ptr_tty_dev  [in] 需要初始化的串口设备
 * @param s32_speed       [in] 串口设备的波特率
 * @return mv_s32_t 
 * - success : MV_EC_SUCCESS
 * - failed  : < 0
 */
mv_s32_t mvp_uart_serial_init(mv_s32ptr_t p32_serial_fd, mv_cv8ptr_t cv8ptr_tty_dev, mv_s32_t s32_speed);

/**
 * @brief 串口设备反初始化
 * @param p32_serial_fd   [in] 需要反初始化的串口设备fd
 * @return mv_void_t 
 */
mv_void_t mvp_uart_serial_destroy(mv_s32ptr_t p32_serial_fd);

/**
 * @brief 读取串口设备数据
 * @param s32_serial_fd     [in] 串口设备的fd
 * @param v8ptr_buff        [in] 保存串口数据buff
 * @param s32_readout_size  [in] 需要读取的数据长度
 * @param s32_timeout_10ms  [in] 超时时间 单位10ms
 * @return mv_s32_t 
 * - success : 已读取的数据长度
 * - failed  : < 0
 */
mv_s32_t mvp_uart_serial_read(mv_s32_t s32_serial_fd, mv_v8ptr_t v8ptr_buff, mv_s32_t s32_readout_size, mv_s32_t s32_timeout_10ms, mv_s32_t s32_read_once);

/**
 * @brief 往串口设备写入数据
 * @param s32_serial_fd     [in] 串口设备的fd
 * @param cv8ptr_buff       [in] 需要写入的数据地址
 * @param s32_buff_len      [in] 需要写入的长度
 * @return mv_s32_t 
 * - success : 已写入的数据长度
 * - failed  : < 0
 */
mv_s32_t mvp_uart_serial_write(mv_s32_t s32_serial_fd, mv_cv8ptr_t cv8ptr_buff, mv_s32_t s32_buff_len);

/**
 * @brief 修改串口设备波特率
 * @param s32_serial_fd   [in] 串口设备的fd
 * @param speed_old       [in] 当前的波特率
 * @param speed_new       [in] 设置后的波特率
 * @return mv_s32_t 
 * - success : MV_EC_SUCCESS
 * - failed  : < 0
 */
mv_s32_t mvp_uart_serial_speed_change(mv_s32_t s32_serial_fd, mv_s32_t speed_old, mv_s32_t speed_new);

/**
 * @brief 刷新设备缓冲
 * @param s32_serial_fd   [in] 串口设备的fd
 * @return mv_s32_t 
 * - success : MV_EC_SUCCESS
 * - failed  : < 0
 */
mv_s32_t mvp_uart_serial_cache_reset(mv_s32_t s32_serial_fd);

//=============================== [dev communication] ==============================//
/**
 * @brief 初始化通信设备
 * @param s32_serial_fd     [in] 通信设备的fd
 * @param cv8ptr_tty_dev    [in] 通信设备节点名
 * @return mv_s32_t 
 * - success : MV_EC_SUCCESS
 * - failed  : < 0
 */
mv_s32_t mvp_dev_init(mv_s32ptr_t p32_serial_fd, mv_cv8ptr_t cv8ptr_tty_dev);

/**
 * @brief 反初始化通信设备
 * @param s32_serial_fd     [in] 通信设备的fd
 * @return mv_s32_t 
 * - success : MV_EC_SUCCESS
 * - failed  : < 0
 */
mv_void_t mvp_dev_destroy(mv_s32ptr_t p32_serial_fd);

/**
 * @brief 向通信设备读取数据
 * @param s32_serial_fd     [in] 通信设备的fd
 * @param v8ptr_buff        [out] 
 * @param s32_readout_size  [in] 需要读取的数据长度，如果是阻塞读取则读满或者超时才会退出
 * @param s32_timeout_10ms  [in] 超时时间
 * @param block             [in] 是否阻塞读取，如果是阻塞读取则读满或者超时才会退出，非阻塞读取则读到一次内容就退出
 * @return mv_s32_t 
 * - success : MV_EC_SUCCESS
 * - failed  : < 0
 */
mv_s32_t mvp_dev_read(mv_s32_t s32_serial_fd, mv_v8ptr_t v8ptr_buff, mv_s32_t s32_readout_size, mv_s32_t s32_timeout_10ms, mv_s32_t block);

/**
 * @brief 向通信设备写数据(直接写)
 * @param s32_serial_fd     [in] 通信设备的fd
 * @param cv8ptr_buff       [in] 写入的数据
 * @param s32_buff_len      [in] 数据长度
 * @return mv_s32_t 
 * - success : MV_EC_SUCCESS
 * - failed  : < 0
 */
mv_s32_t mvp_dev_write(mv_s32_t s32_serial_fd, mv_cv8ptr_t cv8ptr_buff, mv_s32_t s32_buff_len);

//=============================== [zoom] ==============================//
typedef enum _zoom_type
{
  ZOOM_NOT_SUPPORT          = 0,  /* 不支持 */
  ZOOM_OPTICAL_ONLY_SCALE   = 1,  /* 仅支持光学变倍 */
  ZOOM_DIGIT_ONLY_GEAR_SW   = 2,  /* 仅支持长短焦镜头切换 */
  ZOOM_OPTICAL_FOCUS_SCALE  = 3,  /* 支持光学变焦变倍 */
  ZOOM_DIGIT_ONLY_SCALE     = 4,  /* 支持数字变倍 */
}MVP_ZOOM_TYPE_E;

typedef enum _zoom_cmd
{
	ZOOM_STOP,				      //停止行动
	ZOOM_SCALE_SHORT,			  //变倍短
	ZOOM_SCALE_LONG,				//变倍长
	ZOOM_FOCUS_SHORT,			  //聚焦短
	ZOOM_FOCUS_LONG,				//聚焦长
	ZOOM_RESET,				      //镜头复位
	ZOOM_SCALE_GET,				  //查询倍数
	ZOOM_QUERY_STATUS,			//查询状态
	ZOOM_LOCK_FOCAL,				//锁焦
	ZOOM_UPDATE,					  //串口升级	
	ZOOM_VERSION,					  //版本查询
	ZOOM_AUTO_FOCUS,				//自动聚焦
	ZOOM_SELF_CHECK,				//镜头自检
	ZOOM_SET_POS,					  //设置预置位
	ZOOM_RUN_POS,					  //执行预置位
	ZOOM_IPC_REQUEST_DATA,	//请求镜头数据进行保存
  ZOOM_SCALE_SET,	        //设置变倍倍数
  ZOOM_CUT_LONG,	        //镜头切长焦(多镜头就逐级放大)
  ZOOM_CUT_SHORT,	        //镜头切短焦(多镜头就逐级缩小)
	ZOOM_UNUSED,					  //空闲状态
	ZOOM_CMD_MAX = ZOOM_UNUSED,

	ZOOM_UNDEF,
}MVP_ZOOM_CMD_E;

typedef struct _zoom_param
{
  MVP_ZOOM_TYPE_E zoom_type;
  mv_s32_t zoom_scale_num;
    
}MVP_ZOOM_PARAM;

mv_s32_t mvp_zoom_init(MVP_ZOOM_PARAM *zoom_param);
mv_s32_t mvp_zoom_set(MVP_ZOOM_CMD_E cmd, mv_s32_t scale_num);
// mv_s32_t mvp_zoom_status_get();
mv_s32_t mvp_zoom_scale_get();
mv_s32_t mvp_zoom_scale_update(mv_s32_t scale_num);
mv_s32_t mvp_zoom_mode_set(mv_s32_t mode);
mv_s32_t mvp_zoom_uninit();

//=============================== [ircut] ==============================//
typedef enum _ircut_mode
{
  IRCUT_A0_B0,
  IRCUT_A0_B1,
  IRCUT_A1_B0,
  IRCUT_A1_B1,
}MVP_IRCUT_MODE_E;

/**
 * @brief ircut 初始化，不需要则空实现
 * 
 * @return mv_s32_t 
 */
mv_s32_t mvp_ircut_init();

/**
 * @brief ircut 模式设置
 * 
 * @param mode [in] < MVP_IRCUT_MODE_E >
 * @return mv_s32_t 
 */
mv_s32_t mvp_ircut_mode_set(MVP_IRCUT_MODE_E mode);

/**
 * @brief ircut 反初始化，不需要则空实现
 * 
 * @return mv_s32_t 
 */
mv_s32_t mvp_ircut_uninit();

//=============================== [efuse] ==============================//

/**
 * @brief 读取设备efuse id
 * @return mv_u64_t 
 * - success : >  0 设备efuse id
 * - failed  : <= 0
 */
mv_u64_t mvp_efuse_id_get();

//=============================== [mvp_update] ==============================//
/*****************************
*  暂时只有300L在使用
*****************************/
#ifdef AKV300L
mv_s32_t mvp_update_flag_get(mv_u8ptr_t pu8_backup_flag, mv_v8ptr_t v8ptr_image_sig);

mv_s32_t mvp_update_flag_set(mv_v8ptr_t v8ptr_image_sig, mv_s32_t _s32_partion_len);
#endif

#if __cplusplus
}
#endif

#endif